/*
MIT License

Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo
*/

#ifndef simodo_interpret_Interpret_interface
#define simodo_interpret_Interpret_interface

/*! \file Interpret_interface.h
    \brief .
*/

#include "simodo/interpret/StackOfNames_interface.h"
#include "simodo/interpret/ExpressionPrimitives_interface.h"
#include "simodo/interpret/Parallelize_interface.h"
#include "simodo/interpret/FlowLayerInfo.h"
#include "simodo/interpret/InterpretType.h"
#include "simodo/loom/Fiber_interface.h"

namespace simodo::loom
{
    class Loom_interface;
}

namespace simodo::interpret
{
    inline const std::u16string SELF_VARIABLE_NAME      { u"self" };

    struct BreakPoint
    {
        std::string             uri;
        inout::position_line_t  line;
    };

    class Interpret_interface 
    {
    public:
        virtual ~Interpret_interface() = default;

        virtual loom::Fiber_interface * fiber()                 = 0;
        const loom::Fiber_interface *   fiber()                 const 
        { 
            auto thi = const_cast<Interpret_interface *>(this);
            return thi->fiber(); 
        }

        virtual StackOfNames_interface &    stack()             = 0;
        const StackOfNames_interface &      stack()             const 
        { 
            auto thi = const_cast<Interpret_interface *>(this);
            return thi->stack(); 
        }

        virtual ExpressionPrimitives_interface &expr()          = 0;
        const ExpressionPrimitives_interface &  expr()          const 
        { 
            auto thi = const_cast<Interpret_interface *>(this);
            return thi->expr(); 
        }

        virtual Parallelize_interface &     parallelize()       = 0;
        const Parallelize_interface &       parallelize()       const 
        { 
            auto thi = const_cast<Interpret_interface *>(this);
            return thi->parallelize(); 
        }

        virtual void instantiateSemantics(interpret::SemanticModules semantic_modules) = 0;

        virtual const inout::uri_set_t &    files()             const = 0;
        virtual inout::Reporter_abstract &  reporter()          const = 0;
        virtual bool                        errors()            const = 0;
        virtual void                        setStopByError(bool stop_by_error = true) = 0;
        virtual const FlowLayerInfo &       flow()              const = 0;
        virtual InterpretType               type()              const = 0;

        virtual void                        setErrorSign(bool error_sign=true)               = 0;
        virtual void                        addFile(const std::string & path_to_file)        = 0;

        virtual void                        addFlowLayer(const ast::Node & code, 
                                                       boundary_index_t boundary_index, 
                                                       std::function<void (const FlowLayerInfo &)> on_layer_end = nullptr) = 0;
        void                                addFlowLayer(const ast::Node & code, 
                                                        std::function<void (const FlowLayerInfo &)> on_layer_end = nullptr)
                                            { addFlowLayer(code, UNDEFINED_BOUNDARY_INDEX, on_layer_end); }
        virtual bool                        flushLayers(const ast::Node & code, bool invoke_callback) = 0;

        virtual bool                        execute(const ast::Node & code) = 0;
        virtual loom::FiberStatus           executeOperation()              = 0;
        virtual const ast::Node *           lookupOperationNode(int shift=0,
                                                                boundary_index_t bound=UNDEFINED_BOUNDARY_INDEX) const = 0;

        virtual boundary_index_t            copyBaseBounds(const StackOfNames_interface & other) = 0;

        virtual loom::Loom_interface *      loom()                          = 0;
        virtual void                        addBreakPoints(const std::vector<BreakPoint> & breakpoints)    = 0;
        virtual std::vector<BreakPoint>     breakpoints()             const = 0;
    };
}

#endif // simodo_interpret_Interpret_interface
